#include "clkPartitioner.h"

void clkPartitioner::init(float a_cellWidth, float a_cellHeight)
{
	m_cellWidth = a_cellWidth;
	m_cellHeight = a_cellHeight;
}

void clkPartitioner::destroy()
{
	for(int i = 0; i < m_cells.size(); i++)
	{
		m_cells[i]->destroy();
		m_pool.deleteData(&m_cells[i]);
	}
	m_cells.release();
	m_pool.release();
}

void clkPartitioner::partition(clkObject* a_object)
{
	clkCell gCell;
	float gCol = floor(a_object->getPosition().x/m_cellWidth);
	float gRow = floor(a_object->getPosition().y/m_cellHeight);
	V2DF  gPos(
		gCol*m_cellWidth+m_cellWidth/2.0f,
		gRow*m_cellHeight+m_cellHeight/2.0f);
	gCell.init(gPos,gCol,gRow);
	
	clkCell* cell = 0;
	createCell(&cell,&gCell);
	cell->add(a_object);

	float cw = m_cellWidth;
	float ch = m_cellHeight;

	clkAABB gCirs[8];
	gCirs[0] = genAABB(gPos+V2DF(-cw,-ch),cw,ch);
	gCirs[1] = genAABB(gPos+V2DF(0,-ch)  ,cw,ch);
	gCirs[2] = genAABB(gPos+V2DF(cw,-ch) ,cw,ch);
	gCirs[3] = genAABB(gPos+V2DF(cw,0)   ,cw,ch);
	gCirs[4] = genAABB(gPos+V2DF(cw,ch)  ,cw,ch);
	gCirs[5] = genAABB(gPos+V2DF(0,ch)   ,cw,ch);
	gCirs[6] = genAABB(gPos+V2DF(-cw,ch) ,cw,ch);
	gCirs[7] = genAABB(gPos+V2DF(-cw,0)  ,cw,ch);

	clkCell gCells[8];
	gCells[0].init(gPos+V2DF(-cw,-ch),gCol-1,gRow-1);
	gCells[1].init(gPos+V2DF(0,-ch)  ,gCol  ,gRow-1);
	gCells[2].init(gPos+V2DF(cw,-ch) ,gCol+1,gRow-1);
	gCells[3].init(gPos+V2DF(cw,0)   ,gCol+1,gRow);
	gCells[4].init(gPos+V2DF(cw,ch)  ,gCol+1,gRow+1);
	gCells[5].init(gPos+V2DF(0,ch)   ,gCol  ,gRow+1);
	gCells[6].init(gPos+V2DF(-cw,ch) ,gCol-1,gRow+1);
	gCells[7].init(gPos+V2DF(-cw,0)  ,gCol-1,gRow);

	for(int i = 0; i < 8; i++)
	{
		if(overlapAABB(a_object->m_aabb,gCirs[i]))
		{
			clkCell* olap = 0;
			createCell(&olap,&gCells[i]);
			olap->add(a_object);
		}
	}

	int abc = 0;
}

void clkPartitioner::clearCells()
{
	for(int i = 0; i < m_cells.size(); i++)
	{
		m_cells[i]->destroy();
		m_pool.deleteData(&m_cells[i]);
	}
	m_cells.clear();
}

bool clkPartitioner::cellExist(clkCell** a_out, clkCell* a_test)
{
	for(int i = 0; i < m_cells.size(); i++)
	{
		if(a_test->m_col == m_cells[i]->m_col
			&& a_test->m_row == m_cells[i]->m_row)
		{
			*a_out = m_cells[i];
			return true;
		}
	}
	a_out = 0;
	return false;
}

bool clkPartitioner::createCell(clkCell** a_out, clkCell* a_test)
{
	clkCell* cell = 0;
	if(cellExist(&cell,a_test))
	{
		*a_out = cell;
		return false;
	}
	else
	{
		cell = m_pool.newData();
		cell->init(a_test->m_pos,a_test->m_col,a_test->m_row);
		m_cells.insertBack(cell);
		*a_out = cell;
		return true;
	}
}

void clkPartitioner::getCellPos(List<V2DF*>* m_pos)
{
	for(int i = 0; i < m_cells.size(); i++)
		m_pos->insertBack(&m_cells[i]->m_pos);
}